package com.boho.ecp.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import cn.boho.framework.log.LogService;
import cn.boho.framework.log.Logger;
import cn.boho.framework.service.MessageService;


public class SeqManager {
	
	private static Logger logger = LogService.newInstance().getLogger(SeqManager.class.getName());
	
	private static String CONF_FILE = "";
	private static final String CONF_DATE_FIELD = "date";
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
	private SimpleDateFormat sdfStore = new SimpleDateFormat("yyyyMMdd");
	private Properties prop = new Properties();
	
	private Long seq = 1L;
	private Long date;
	private int zeroCount = 4;

	private FileInputStream fis;
	private FileOutputStream fos;
	
	private static SeqManager sm = null;
	
	public static SeqManager getInstance(){
		if(sm == null){
			sm = new SeqManager();
		}
		return sm;
	}
	
	private SeqManager(){
		this.readSeq();
	}
	
	private void setDateFormat(String format){
		sdf = new SimpleDateFormat(format);
	}
	
	public void setZeroCount(int zeroCount) {
		this.zeroCount = zeroCount;
	}
	
	private void readSeq(){
		try {
			CONF_FILE = MessageService.getMessage("seq_path");
			fis = new FileInputStream(CONF_FILE);
			prop.load(fis);
			date = Long.valueOf(prop.getProperty(CONF_DATE_FIELD, sdfStore.format(new Date())));
		} catch (FileNotFoundException e) {
			logger.error("Read SEQ File Not Found!");
		} catch (IOException e) {
			logger.error("Read SEQ IOException!");
		} finally{
			if(fis != null){
				try {
					fis.close();
				} catch (IOException e) {
					logger.error("IOException Close!");
				}
			}
		}
	}
	
	private Long genSeq(){
		String date = compareDate();
		String seqFormat = String.format("%0"+ zeroCount +"d", seq);
		seq++;
		return Long.parseLong((date + seqFormat));
	}
	
	private String compareDate(){
		Date d = new Date();
		Long now = Long.valueOf(sdfStore.format(d));
		if(date < now){
			date = now;
			seq = 1L;
		}
		return sdf.format(d);
	}
	
	/**
	 * 保存当前序列号
	 */
	private void storeSeq(String seqName){
		try {
			fos = new FileOutputStream(CONF_FILE);
			prop.setProperty(seqName, seq.toString());
			prop.setProperty(CONF_DATE_FIELD, date.toString());
			prop.store(fos, "");
		} catch (FileNotFoundException e) {
			logger.error("Store SEQ File Not Found!");
		} catch (IOException e) {
			logger.error("Store SEQ IOException!");
		} finally {
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					logger.error("IOException Close!");
				}
			}
		}
	}
	
	/**
	 * 获取生成的序列号
	 * @return
	 */
	public synchronized Long getSeq(String format, String seqName){
		if(format != null){
			setDateFormat(format);
		}
		seq = Long.valueOf(prop.getProperty(seqName, "1"));
		Long result = genSeq();
		storeSeq(seqName);
		return result;
	}
	
	public synchronized Long getSeq(String seqName){
		return getSeq(null, seqName);
	}
}
